﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using UploadClient.Utilitys;

namespace UploadClient
{
    public partial class ExceptionWindow : Window
    {
        readonly List<string> ExceptionInformationList = new List<string>();

        public ExceptionWindow(string messageTitle, string message, Bitmap image, Exception ex, string windowTitle)
        {
            InitializeComponent();

            this.Title = windowTitle;
            error_Titel.Content = messageTitle;
            error_Text.Text = message;
            error_Image.Source = ImageHelpers.GetBitmapSource(image);

            if (ex != null)
            {
                error_TreeView.Visibility = Visibility.Visible;
                error_TreeViewText.Visibility = Visibility.Visible;
                error_ClipboardButton.Visibility = Visibility.Visible;

                TreeViewItem treeViewItem = new TreeViewItem();
                treeViewItem.Header = "Exception Details";

                BuildTreeLayer(ex, treeViewItem);
                error_TreeView.Items.Add(treeViewItem);
            }
        }

        public ExceptionWindow(Exception ex)
        {
            InitializeComponent();

            this.Title = "Exception";
            error_Titel.Content = this.Title;
            error_Text.Text = ex.Message;
            error_Image.Source = ImageHelpers.GetBitmapSource(SystemIcons.Error.ToBitmap());

            error_TreeView.Visibility = Visibility.Visible;
            error_TreeViewText.Visibility = Visibility.Visible;
            error_ClipboardButton.Visibility = Visibility.Visible;

            TreeViewItem treeViewItem = new TreeViewItem();
            treeViewItem.Header = "Exception Details";

            BuildTreeLayer(ex, treeViewItem);
            error_TreeView.Items.Add(treeViewItem);
        }

        void BuildTreeLayer(Exception e, TreeViewItem parent)
        {
            String exceptionInformation = "\n\n      ####" + e.GetType().ToString() + "####\n";
            parent.DisplayMemberPath = "Header";
            parent.Items.Add(new TreeViewStringSet() { Header = "Type", Content = e.GetType().ToString() });
            PropertyInfo[] memberList = e.GetType().GetProperties();
            foreach (PropertyInfo info in memberList)
            {
                var value = info.GetValue(e, null);
                if (value != null)
                {
                    if (info.Name == "InnerException")
                    {
                        TreeViewItem treeViewItem = new TreeViewItem();
                        treeViewItem.Header = info.Name;
                        BuildTreeLayer(e.InnerException, treeViewItem);
                        parent.Items.Add(treeViewItem);
                    }
                    else
                    {
                        TreeViewStringSet treeViewStringSet = new TreeViewStringSet() { Header = info.Name, Content = value.ToString() };
                        parent.Items.Add(treeViewStringSet);
                        exceptionInformation += treeViewStringSet.Header + ":\n" + treeViewStringSet.Content + "\n\n";
                    }
                }
            }
            ExceptionInformationList.Add(exceptionInformation);
        }

        private void Error_TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (e.NewValue.GetType() == typeof(TreeViewItem)) error_TreeViewText.Text = "";
            else error_TreeViewText.Text = e.NewValue.ToString();
        }

        private void Error_ClipboardButton_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(string.Format("ErrorTime: {0}\n\n", DateTime.Now));
            sb.Append(string.Format("OperationSystemVersion: {0}\n", Environment.OSVersion));
            sb.Append(string.Format("SoftwareVersion: {0}\n\n", Assembly.GetExecutingAssembly().GetName().Version.ToString())); 

            foreach (string info in ExceptionInformationList) sb.Append(info);
            Clipboard.SetText(sb.ToString());
        }

        private void Error_CloseButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        #region Nested type: TreeViewStringSet

        private class TreeViewStringSet
        {
            public string Header { get; set; }
            public string Content { get; set; }

            public override string ToString()
            {
                return Content;
            }
        }

        #endregion
    }
}
